unit UMonoIntf;

interface
const
    External_library = 'C:\Program Files\Mono-2.8.1\bin\mono-2.0.dll';
    MONODLL = 'mono-2.0.dll';
    MONO_ZERO_LEN_ARRAY = 1; // 1 o zero ?

 {$Z4}    //Minimum enumeration size
type

  int8_t = smallint;
  uint8_t = byte;
  int16_t = smallint;
  uint16_t = word;
  int32_t = integer;
  uint32_t = cardinal;
  int64_t = int64;
  uint64_t = uInt64;

  mono_bool = longbool;//int32_t;
  mono_byte = uint8_t;
	mono_unichar2 = uint16_t;

  PPointer = ^Pointer;
  TMonoDomain = Pointer; 
  PMonoDomain  = ^TMonoDomain;
  TMonoAssembly = Pointer;
  PMonoAssembly = ^TMonoAssembly;
  TMonoImage = Pointer;
  PMonoImage = ^TMonoImage;
  TMonoClass = Pointer;
  PMonoClass  = ^TMonoClass;
  TMonoMethod = Pointer;
  PMonoMethod = ^TMonoMethod;

  TMonoVTable = Pointer;
  PMonoVTable = ^TMonoVTable;
  TMonoThreadsSync = Pointer;
  PMonoThreadsSync = ^TMonoThreadsSync;

  PMonoObject = ^TMonoObject;
  TMonoObject = record
      vtable : PMonoVTable;
      synchronisation : PMonoThreadsSync;
   end;

  TMonoString = packed record
    FObject: TMonoObject;
    length: int32_t;
    chars: array [0..(MONO_ZERO_LEN_ARRAY)-1] of WideChar;
  end;
  PMonoString  = ^Pointer; // hidden
  PPMonoString = ^PMonoString;
  TMonoClassField = Pointer;
  PMonoClassField = ^TMonoClassField;
  TMonoGenericParam = Pointer;
  PMonoGenericParam = ^TMonoGenericParam;
  TMonoGenericClass = Pointer;
  PMonoGenericClass = ^TMonoGenericClass;

  PMonoCustomMod = ^TMonoCustomMod;
  TMonoCustomMod = packed record
     flags: cardinal; // bit field
     //required: 1;
	   //token: 31;
     function required: cardinal;
     function token: cardinal;
  end;

  PMonoArrayType = ^TMonoArrayType;
  TMonoArrayType = packed record  // allineamento 4 byte c
      eklass : PMonoClass;
      rank : uint8_t;
      numsizes : uint8_t;
      numlobounds : uint8_t;
      sizes : Plongint;
      lobounds : Plongint;
   end;

TMonoTypeEnum = (
  MONO_TYPE_END = $00,
  MONO_TYPE_VOID = $01,
  MONO_TYPE_BOOLEAN = $02,
  MONO_TYPE_CHAR = $03,
  MONO_TYPE_I1 = $04,
  MONO_TYPE_U1 = $05,
  MONO_TYPE_I2 = $06,
  MONO_TYPE_U2 = $07,
  MONO_TYPE_I4 = $08,
  MONO_TYPE_U4 = $09,
  MONO_TYPE_I8 = $0a,
  MONO_TYPE_U8 = $0b,
  MONO_TYPE_R4 = $0c,
  MONO_TYPE_R8 = $0d,
  MONO_TYPE_STRING = $0e,
  MONO_TYPE_PTR = $0f,
  MONO_TYPE_BYREF = $10,
  MONO_TYPE_VALUETYPE = $11,
  MONO_TYPE_CLASS = $12,
  MONO_TYPE_VAR = $13,
  MONO_TYPE_ARRAY = $14,
  MONO_TYPE_GENERICINST = $15,
  MONO_TYPE_TYPEDBYREF = $16,
  MONO_TYPE_I = $18,
  MONO_TYPE_U = $19,
  MONO_TYPE_FNPTR = $1b,
  MONO_TYPE_OBJECT = $1c,
  MONO_TYPE_SZARRAY = $1d,
  MONO_TYPE_MVAR = $1e,
  MONO_TYPE_CMOD_REQD = $1f,
  MONO_TYPE_CMOD_OPT = $20,
  MONO_TYPE_INTERNAL = $21,
  MONO_TYPE_MODIFIER = $40,
  MONO_TYPE_SENTINEL = $41,
  MONO_TYPE_PINNED = $45,
  MONO_TYPE_ENUM = $55);

  PMonoType = ^TMonoType;
  TMonoType = packed record
      data: packed record
        case longint of
           0 : ( klass : PMonoClass );
           1 : ( type_ : PMonoType );
           2 : ( array_ : PMonoArrayType );
           3 : ( method : Pointer);  // PMonoMethodSignature
           4 : ( generic_param : PMonoGenericParam );
           5 : ( generic_class : PMonoGenericClass );
        end;
      flags: cardinal; //bit field 32 bit
//      attrs: cardinal; :16
//      type_: TMonoTypeEnum;  :8
//      num_mods: cardinal; :6
//      byref: cardinal; :1
//      pinned: cardinal; :1
      modifiers : array[0..(MONO_ZERO_LEN_ARRAY)-1] of TMonoCustomMod;
      function attrs: cardinal;
      function type_: TMonoTypeEnum;
      function num_mods: cardinal;
      function byRef: cardinal;
      function pinned: cardinal;
   end;
(*
struct _MonoType {
	union {
		MonoClass *klass; /* for VALUETYPE and CLASS */
		MonoType *type;   /* for PTR */
		MonoArrayType *array; /* for ARRAY */
		MonoMethodSignature *method;
		MonoGenericParam *generic_param; /* for VAR and MVAR */
		MonoGenericClass *generic_class; /* for GENERICINST */
	} data;
	unsigned int attrs    : 16; /* param attributes or field flags */
	MonoTypeEnum type     : 8;
	unsigned int num_mods : 6;  /* max 64 modifiers follow at the end */
	unsigned int byref    : 1;
	unsigned int pinned   : 1;  /* valid when included in a local var signature */
	MonoCustomMod modifiers [MONO_ZERO_LEN_ARRAY]; /* this may grow */
};
*)

  PMonoMethodSignature = ^TMonoMethodSignature;
  TMonoMethodSignature = packed record // allineamento 4 byte c
      flag0 : longint;
      param_count : word; unused1: word;
      sentinelpos : smallint; unused2: word;
      flag1 : longint;
      ret : PMonoType;
      params : array[0..(MONO_ZERO_LEN_ARRAY)-1] of PMonoType;
   end;





  TMonoDelegate = Pointer;
  PMonoDelegate = ^TMonoDelegate;

  PMonoArrayBounds = ^TMonoArrayBounds;
  TMonoArrayBounds = packed record // allinare a 4 byte
      length : cardinal;
      lower_bound : integer;
   end;


  PMonoArray = ^TMonoArray;
  TMonoArray = packed record // allineare a 4 byte
      obj : TMonoObject;
      bounds : PMonoArrayBounds;
      max_length : cardinal;
      vector : array[0..(MONO_ZERO_LEN_ARRAY)-1] of double;
   end;
   PPMonoArray = ^PMonoArray;
   TMonoProperty = Pointer;
   PMonoProperty = ^TMonoProperty;

   TMonoEvent = Pointer;
   PMonoEvent = ^TMonoEvent;

   TMonoMethodDesc = Pointer;
   PMonoMethodDesc = ^TMonoMethodDesc;

   TMonoThread = Pointer;
   PMonoThread = ^TMonoThread;

const
  FIELD_ATTRIBUTE_FIELD_ACCESS_MASK     = $0007;
  FIELD_ATTRIBUTE_COMPILER_CONTROLLED   = $0000;
  FIELD_ATTRIBUTE_PRIVATE               = $0001;
  FIELD_ATTRIBUTE_FAM_AND_ASSEM         = $0002;
  FIELD_ATTRIBUTE_ASSEMBLY              = $0003;
  FIELD_ATTRIBUTE_FAMILY                = $0004;
  FIELD_ATTRIBUTE_FAM_OR_ASSEM          = $0005;
  FIELD_ATTRIBUTE_PUBLIC                = $0006;

  FIELD_ATTRIBUTE_STATIC                = $0010;
  FIELD_ATTRIBUTE_INIT_ONLY             = $0020;
  FIELD_ATTRIBUTE_LITERAL               = $0040;
  FIELD_ATTRIBUTE_NOT_SERIALIZED        = $0080;
  FIELD_ATTRIBUTE_SPECIAL_NAME          = $0200;
  FIELD_ATTRIBUTE_PINVOKE_IMPL          = $2000;


  TYPE_ATTRIBUTE_VISIBILITY_MASK      = $00000007;
  TYPE_ATTRIBUTE_NOT_PUBLIC           = $00000000;
  TYPE_ATTRIBUTE_PUBLIC               = $00000001;
  TYPE_ATTRIBUTE_NESTED_PUBLIC        = $00000002;
  TYPE_ATTRIBUTE_NESTED_PRIVATE       = $00000003;
  TYPE_ATTRIBUTE_NESTED_FAMILY        = $00000004;
  TYPE_ATTRIBUTE_NESTED_ASSEMBLY      = $00000005;
  TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM = $00000006;
  TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM  = $00000007;
  TYPE_ATTRIBUTE_LAYOUT_MASK          = $00000018;
  TYPE_ATTRIBUTE_AUTO_LAYOUT          = $00000000;
  TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT    = $00000008;
  TYPE_ATTRIBUTE_EXPLICIT_LAYOUT      = $00000010;
  TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK  = $00000020;
  TYPE_ATTRIBUTE_CLASS                = $00000000;
  TYPE_ATTRIBUTE_INTERFACE            = $00000020;
  TYPE_ATTRIBUTE_ABSTRACT             = $00000080;
  TYPE_ATTRIBUTE_SEALED               = $00000100;
  TYPE_ATTRIBUTE_SPECIAL_NAME         = $00000400;
  TYPE_ATTRIBUTE_IMPORT               = $00001000;
  TYPE_ATTRIBUTE_SERIALIZABLE         = $00002000;
  TYPE_ATTRIBUTE_STRING_FORMAT_MASK   = $00030000;
  TYPE_ATTRIBUTE_ANSI_CLASS           = $00000000;
  TYPE_ATTRIBUTE_UNICODE_CLASS        = $00010000;
  TYPE_ATTRIBUTE_AUTO_CLASS           = $00020000;
  TYPE_ATTRIBUTE_BEFORE_FIELD_INIT    = $00100000;
  TYPE_ATTRIBUTE_FORWARDER            = $00200000;
  TYPE_ATTRIBUTE_RESERVED_MASK        = $00040800;
  TYPE_ATTRIBUTE_RT_SPECIAL_NAME      = $00000800;
  TYPE_ATTRIBUTE_HAS_SECURITY         = $00040000;

  METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK        = $0007;
  METHOD_ATTRIBUTE_COMPILER_CONTROLLED       = $0000;
  METHOD_ATTRIBUTE_PRIVATE                   = $0001;
  METHOD_ATTRIBUTE_FAM_AND_ASSEM             = $0002;
  METHOD_ATTRIBUTE_ASSEM                     = $0003;
  METHOD_ATTRIBUTE_FAMILY                    = $0004;
  METHOD_ATTRIBUTE_FAM_OR_ASSEM              = $0005;
  METHOD_ATTRIBUTE_PUBLIC                    = $0006;
  METHOD_ATTRIBUTE_STATIC                    = $0010;
  METHOD_ATTRIBUTE_FINAL                     = $0020;
  METHOD_ATTRIBUTE_VIRTUAL                   = $0040;
  METHOD_ATTRIBUTE_HIDE_BY_SIG               = $0080;
  METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK        = $0100;
  METHOD_ATTRIBUTE_REUSE_SLOT                = $0000;
  METHOD_ATTRIBUTE_NEW_SLOT                  = $0100;
  METHOD_ATTRIBUTE_STRICT                    = $0200;
  METHOD_ATTRIBUTE_ABSTRACT                  = $0400;
  METHOD_ATTRIBUTE_SPECIAL_NAME              = $0800;
  METHOD_ATTRIBUTE_PINVOKE_IMPL              = $2000;
  METHOD_ATTRIBUTE_UNMANAGED_EXPORT          = $0008;


type
  TMonoDebugFormat = (
    MONO_DEBUG_FORMAT_NONE,
	  MONO_DEBUG_FORMAT_MONO,
	  MONO_DEBUG_FORMAT_DEBUGGER);

  PMonoImageOpenStatus = ^TMonoImageOpenStatus;
  TMonoImageOpenStatus = (
    MONO_IMAGE_OK,
    MONO_IMAGE_ERROR_ERRNO,
    MONO_IMAGE_MISSING_ASSEMBLYREF,
    MONO_IMAGE_IMAGE_INVALID);

type
  _mono_jit_init = function (afile:PAnsichar):PMonoDomain;cdecl;
  _mono_jit_init_version = function(root_domain_name: PAnsiChar; runtime_version: PAnsiChar): PMonoDomain; cdecl;
  _mono_jit_exec = function (domain:PMonoDomain; assembly:PMonoAssembly; argc:longint; argv: array of PAnsichar):longint;cdecl;
  _mono_jit_cleanup = procedure (domain:PMonoDomain);cdecl;
  _mono_jit_parse_options = procedure (argc: integer; argv: array of PAnsichar); cdecl;
  _mono_debug_init = procedure (format: TMonoDebugFormat); cdecl;
  _mono_domain_assembly_open = function (domain:PMonoDomain; name:PAnsichar):PMonoAssembly;cdecl;
  _mono_add_internal_call = procedure (name: PAnsichar; method: pointer);cdecl;
  _mono_assembly_get_image = function (assembly: PMonoAssembly): PMonoImage;cdecl;
  _mono_class_from_name = function (image:PMonoImage; name_space:PAnsichar; name:PAnsichar):PMonoClass;cdecl;
  _mono_class_get_field_from_name = function (klass:PMonoClass; name:Pansichar):PMonoClassField;cdecl;
  _mono_type_get_type = function (_type:PMonoType):TMonoTypeEnum;cdecl;
  _mono_type_is_byref = function (_type:PMonoType):longbool;cdecl;
  _mono_type_get_name = function (_type:PMonoType):PAnsichar;cdecl;
  _mono_class_get_method_from_name = function (klass:PMonoClass; name: PAnsiChar; param_count: integer):PMonoMethod;cdecl;
  _mono_class_get_methods = function (klass:PMonoClass; var iter: pointer):PMonoMethod;cdecl;
  _mono_class_get_fields = function (klass:PMonoClass; var iter:pointer):PMonoClassField;cdecl;
  _mono_class_get_properties = function (klass: PMonoClass; var iter:pointer):PMonoProperty;cdecl;
  _mono_class_get_events = function (klass: PMonoClass; var iter:pointer):PMonoEvent;cdecl;
  _mono_class_get_property_from_name = function (klass: PMonoClass; name:PAnsichar):PMonoProperty;cdecl;
  _mono_property_get_get_method = function (prop: PMonoProperty):PMonoMethod;cdecl;
  _mono_property_get_value = function (prop: PMonoProperty; obj:PPointer; var params; var exc:PMonoObject):PMonoObject;cdecl;
  _mono_property_set_value = procedure (prop: PMonoProperty; obj:PPointer; var params; var exc:PMonoObject);cdecl;
  _mono_property_get_name = function (prop: PMonoProperty):PAnsichar;cdecl;
  _mono_property_get_set_method = function (prop: PMonoProperty):PMonoMethod;cdecl;
  _mono_property_get_parent = function (prop: PMonoProperty):PMonoClass;cdecl;
  _mono_property_get_flags = function (prop: PMonoProperty):Cardinal;cdecl;
  _mono_method_get_name = function (method: PMonoMethod):PAnsichar;cdecl;
  _mono_method_signature = function (method:PMonoMethod):PMonoMethodSignature;cdecl;
  _mono_signature_get_param_count = function (sig:PMonoMethodSignature):cardinal;cdecl;
  _mono_signature_get_params = function (sig: PMonoMethodSignature; var iter:pointer):PMonoType;cdecl;
  _mono_signature_get_return_type = function (sig:PMonoMethodSignature):PMonoType;cdecl;
  _mono_signature_get_desc = function (sig: PMonoMethodSignature; include_namespace: longbool): PAnsichar;cdecl;
  _mono_signature_is_instance = function (sig: PMonoMethodSignature):longbool;cdecl;
  _mono_signature_vararg_start = function (sig: PMonoMethodSignature):longint;cdecl;
  _mono_object_get_virtual_method = function (obj:PMonoObject; method:PMonoMethod):PMonoMethod;cdecl;
  _mono_class_is_valuetype = function (klass:PMonoClass):longbool;cdecl;
  _mono_method_get_class = function (method:PMonoMethod):PMonoClass;cdecl;
  _mono_class_get_name = function (klass:PMonoClass):PAnsichar;cdecl;
  _mono_class_get_namespace = function (klass: PMonoClass): PAnsiChar; cdecl;
  _mono_class_get_image = function (klass: PMonoClass): PMonoImage; cdecl;
  _mono_type_full_name = function (_type: PMonoType): PAnsiChar; cdecl;
  _mono_class_from_mono_type = function (_type: PMonoType): PMonoClass; cdecl;
  _mono_class_get_parent = function (klass:PMonoClass):PMonoClass;cdecl;
  _mono_object_new = function (domain: PMonoDomain; klass:PMonoClass):PMonoObject;cdecl;
  _mono_object_get_class = function (obj:PMonoObject):PMonoClass;cdecl;
  _mono_runtime_object_init = procedure (this_obj: PMonoObject);cdecl;
  _mono_object_unbox = function (obj:PMonoObject):pointer;cdecl;
  _mono_value_box = function (domain:PMonoDomain; klass:PMonoClass; val:pointer):PMonoObject;cdecl;
  _mono_runtime_invoke = function (method:PMonoMethod; obj: PPointer; var params; var exc: PMonoObject):PMonoObject;cdecl;
  _mono_string_new_utf16 = function (domain: PMonoDomain; text: PChar; len: int32_t): PMonoString;cdecl;
  _mono_string_to_byvalwstr = procedure  (dst: pointer; src: PMonoString; size: integer);cdecl;
  _mono_string_to_utf16  = function (s: PMonoString): PChar;cdecl;
  _mono_get_corlib = function (): PMonoImage; cdecl;
  _mono_get_object_class = function ():PMonoClass;cdecl;
  _mono_get_byte_class = function ():PMonoClass;cdecl;
  _mono_get_void_class = function ():PMonoClass;cdecl;
  _mono_get_boolean_class = function ():PMonoClass;cdecl;
  _mono_get_sbyte_class = function ():PMonoClass;cdecl;
  _mono_get_int16_class = function ():PMonoClass;cdecl;
  _mono_get_uint16_class = function ():PMonoClass;cdecl;
  _mono_get_int32_class = function ():PMonoClass;cdecl;
  _mono_get_uint32_class = function ():PMonoClass;cdecl;
  _mono_get_intptr_class = function ():PMonoClass;cdecl;
  _mono_get_uintptr_class = function ():PMonoClass;cdecl;
  _mono_get_int64_class = function ():PMonoClass;cdecl;
  _mono_get_uint64_class = function ():PMonoClass;cdecl;
  _mono_get_single_class = function ():PMonoClass;cdecl;
  _mono_get_double_class = function ():PMonoClass;cdecl;
  _mono_get_char_class = function ():PMonoClass;cdecl;
  _mono_get_string_class = function ():PMonoClass;cdecl;
  _mono_get_enum_class = function ():PMonoClass;cdecl;
  _mono_get_array_class = function ():PMonoClass;cdecl;
  _mono_get_thread_class = function ():PMonoClass;cdecl;
  _mono_get_exception_class = function ():PMonoClass;cdecl;
  _mono_set_dirs = procedure (assembly_dir: PAnsiChar; config_dir: PAnsiChar); cdecl;
  _mono_free = procedure (mem: pointer);cdecl;

  _mono_array_class_get = function(element_class: PMonoClass; rank: uint32_t): PMonoClass; cdecl;
  _mono_array_element_size = function(ac: PMonoClass): int32_t; cdecl;
  _mono_class_array_element_size = function(klass: PMonoClass): int32_t; cdecl;
  _mono_array_new = function (domain: PMonoDomain; eclass: PMonoClass; n: NativeUInt): PMonoArray; cdecl;
  _mono_array_new_full = function (domain: PMonoDomain; array_class: PMonoClass; var lengths: NativeUInt; var lower_bounds: NativeInt): PMonoArray; cdecl;
  _mono_array_new_specific = function( vtable: PMonoVTable; n: NativeUInt): PMonoArray; cdecl;
  _mono_array_clone = function (_array: PMonoArray): PMonoArray; cdecl;
  _mono_array_addr_with_size = function(_array: PMonoArray; size: integer; idx: NativeUInt): PByte;  cdecl; //PChar
  _mono_array_length = function( _array: PMonoArray): NativeUInt; cdecl;
  _mono_value_copy = procedure (dest: Pointer; src: Pointer; klass: PMonoClass); cdecl;
  _mono_value_copy_array = procedure (dest: PMonoArray; dest_idx: integer; src: Pointer; count: integer); cdecl;
  _mono_gchandle_new = function (obj: PMonoObject; pinnded: mono_bool): uint32_t; cdecl;
  _mono_gchandle_new_weakref = function(obj: PMonoObject; track_resurrection: mono_bool): uint32_t; cdecl;
  _mono_gchandle_get_target = function (gchandle: uint32_t): PMonoObject; cdecl;
  _mono_gchandle_free = procedure(gchandle: uint32_t); cdecl;

  _mono_gc_wbarrier_set_field = procedure (obj: PMonoObject; field_ptr: Pointer; value: PMonoObject); cdecl;
  _mono_gc_wbarrier_set_arrayref = procedure (arr: PMonoArray; slot_ptr: Pointer; value: PMonoObject); cdecl;
  _mono_gc_wbarrier_arrayref_copy = procedure (dest_ptr: Pointer; src_ptr: Pointer; count: integer); cdecl;
  _mono_gc_wbarrier_generic_store = procedure (ptr: Pointer; value: PMonoObject); cdecl;
  _mono_gc_wbarrier_generic_nostore = procedure (ptr: Pointer); cdecl;
  _mono_gc_wbarrier_value_copy = procedure (dest: Pointer; src: Pointer; count: integer; klass: PMonoClass); cdecl;
  _mono_gc_wbarrier_object_copy = procedure (obj: PMonoObject; src: PMonoObject); cdecl;
  _mono_gc_collect = procedure(generation: integer); cdecl;
  _mono_gc_max_generation = function (): integer; cdecl;
  _mono_gc_get_generation = function (obj: PMonoObject): integer; cdecl;
  _mono_gc_collection_count = function (generation: integer): integer; cdecl;
  _mono_gc_get_used_size = function (): int64_t;  cdecl;
  _mono_gc_get_heap_size = function (): int64_t;  cdecl;
  _mono_gc_invoke_finalizers = function (): integer;  cdecl;
  _mono_object_castclass_mbyref = function (obj: PMonoObject; klass: PMonoClass): PMonoObject; cdecl;
  _mono_class_get_flags = function(klass: PMonoClass): uint32_t; cdecl;
  _mono_class_vtable = function(domain: PMonoDomain; klass: PMonoClass): PMonoVTable; cdecl;
  _mono_class_interface_offset = function (klass: PMonoClass; itf: PMonoClass): integer; cdecl;
  _mono_class_get_interfaces = function (klass: PMonoClass; var iter: Pointer): PMonoClass; cdecl;
  _mono_class_get_type = function (klass: PMonoClass): PMonoType; cdecl;
  _mono_class_get_byref_type = function (klass: PMonoClass): PMonoType; cdecl;

  _mono_class_instance_size = function (klass: PMonoClass): int32_t; cdecl;
  _mono_class_data_size =  function (klass: PMonoClass): int32_t; cdecl;
  _mono_class_value_size =  function (klass: PMonoClass; var align: uint32_t): int32_t; cdecl;
  _mono_class_min_align =  function (klass: PMonoClass): int32_t; cdecl;

  _mono_field_get_name = function (field: PMonoClassField): PAnsichar; cdecl;
  _mono_field_get_type = function (field: PMonoClassField): PMonoType; cdecl;
  _mono_field_get_flags = function (field: PMonoClassField): uint32_t; cdecl;
  _mono_field_set_value = procedure(obj: PMonoObject; field: PMonoClassField; value: Pointer); cdecl;
  _mono_field_static_set_value = procedure (vt: PMonoVTable; field: PMonoClassField; value: Pointer); cdecl;
  _mono_field_get_value = procedure (obj: PMonoObject; field: PMonoClassField; value: Pointer);cdecl;
  _mono_field_static_get_value = procedure (vt : PMonoVTable; field: PMonoClassField; value: Pointer); cdecl;
  _mono_field_get_value_object = function (domain: PMonoDomain; field: PMonoClassField; obj: PMonoObject): PMonoObject; cdecl;
  _mono_field_get_offset = function (field: PMonoClassField): uint32_t; cdecl;
  _mono_field_get_data = function (field: PMonoClassField): PAnsiChar; cdecl;
  _mono_get_dbnull_object = function (domain: PMonoDomain): PMonoObject; cdecl;

  _mono_runtime_delegate_invoke = function (delegate: PMonoObject; var params; var exc:PMonoObject): PMonoObject; cdecl;
  _mono_get_delegate_invoke = function (klass: PMonoClass): PMonoMethod; cdecl;
  _mono_method_get_unmanaged_thunk = function(method: PMonoMethod): Pointer; cdecl;


  TMonoFunc = procedure (data: Pointer; user_data: Pointer); cdecl;
  TMonoHFunc = procedure (key: Pointer; value: Pointer; user_data: Pointer); cdecl;
  _mono_assembly_foreach = procedure (func: TMonoFunc; user_data: Pointer); cdecl;
  _mono_assembly_open = function (filename: PAnsiChar; status: PMonoImageOpenStatus): PMonoAssembly; cdecl;

  TMonoAssemblyLoadFunc = procedure (assembly: PMonoAssembly; user_data: pointer); cdecl;
  _mono_install_assembly_load_hook = procedure(func: TMonoAssemblyLoadFunc; user_data: Pointer); cdecl;
  _mono_image_get_filename = function (image : PMonoImage): PansiChar; cdecl;
  _mono_image_get_name = function (image : PMonoImage): PansiChar; cdecl;
  _mono_object_get_domain = function (obj: PMonoObject): PMonoDomain; cdecl;
  _mono_domain_get = function (): PMonoDomain; cdecl;
  _mono_domain_get_by_id = function (domainid: integer): PMonoDomain; cdecl;
  _mono_domain_get_id = function (domain: PMonoDomain): integer; cdecl;
  _mono_domain_create_appdomain = function (friendly_name: PAnsiChar; configuration_file: PAnsiChar): PMonoDomain; cdecl;
  _mono_domain_set = function (domain: PMonoDomain; force: mono_bool): mono_bool; cdecl;
  _mono_domain_unload = procedure (domain: PMonoDomain); cdecl;
  _mono_domain_try_unload = procedure(domain: PMonoDomain; var exc: PMonoObject); cdecl;
  TMonoDomainFunc = procedure (domain: PMonoDomain; user_data: Pointer); cdecl;
  _mono_domain_foreach = procedure (func: TMonoDomainFunc; user_data: Pointer); cdecl;

  TMonoThreadManageCallback = function (thread: PMonoThread): mono_bool; cdecl;
  TMonoThreadStartCB = procedure (tid: NativeInt; stack_start: Pointer; func: Pointer); cdecl;
  TMonoThreadAttachCB = procedure (tid: NativeInt; stack_start: Pointer); cdecl;
  _mono_thread_init = procedure (start_cb: TMonoThreadStartCB; attach_cb: TMonoThreadAttachCB); cdecl;
  _mono_thread_cleanup = procedure (); cdecl;
  _mono_thread_manage = procedure (); cdecl;
  _mono_thread_current = function (): PMonoThread; cdecl;
  _mono_thread_set_main = procedure (thread: PMonoThread); cdecl;
  _mono_thread_get_main = function (): PMonoThread; cdecl;
  _mono_thread_stop = procedure(thread: PMonoThread); cdecl;
  _mono_thread_new_init = procedure (tid: NativeInt; stack_start: Pointer; func: Pointer); cdecl;
  _mono_thread_create = procedure (domain: PMonoDomain; func: Pointer; arg: pointer); cdecl;
  _mono_thread_attach = function (domain: PMonoDomain): PMonoThread; cdecl;
  _mono_thread_detach = procedure(thread: PMonoThread); cdecl;
  _mono_thread_set_manage_callback = procedure (thread: PMonoThread; func: TMonoThreadManageCallback); cdecl;
  _mono_threads_set_default_stacksize = procedure (stackSize: uint32_t); cdecl;
  _mono_threads_get_default_stacksize = function (): uint32_t; cdecl;


var
  mono_jit_init: _mono_jit_init;
  mono_jit_init_version: _mono_jit_init_version;
  mono_jit_exec: _mono_jit_exec;
  mono_jit_cleanup: _mono_jit_cleanup;
  mono_jit_parse_options: _mono_jit_parse_options;
  mono_debug_init: _mono_debug_init;
  mono_domain_assembly_open: _mono_domain_assembly_open;
  mono_add_internal_call: _mono_add_internal_call;
  mono_assembly_get_image: _mono_assembly_get_image;
  mono_class_from_name: _mono_class_from_name;
  mono_class_get_field_from_name: _mono_class_get_field_from_name;
  mono_type_get_type: _mono_type_get_type;
  mono_type_is_byref: _mono_type_is_byref;
  mono_type_get_name: _mono_type_get_name;
  mono_class_get_method_from_name: _mono_class_get_method_from_name;
  mono_class_get_methods: _mono_class_get_methods;
  mono_class_get_fields: _mono_class_get_fields;
  mono_class_get_properties: _mono_class_get_properties;
  mono_class_get_events: _mono_class_get_events;
  mono_class_get_property_from_name: _mono_class_get_property_from_name;
  mono_property_get_get_method: _mono_property_get_get_method;
  mono_property_get_value: _mono_property_get_value;
  mono_property_set_value: _mono_property_set_value;
  mono_property_get_name: _mono_property_get_name;
  mono_property_get_set_method: _mono_property_get_set_method;
  mono_property_get_parent: _mono_property_get_parent;
  mono_property_get_flags: _mono_property_get_flags;
  mono_method_get_name: _mono_method_get_name;
  mono_method_signature: _mono_method_signature;
  mono_signature_get_param_count: _mono_signature_get_param_count;
  mono_signature_get_params: _mono_signature_get_params;
  mono_signature_get_return_type: _mono_signature_get_return_type;
  mono_signature_get_desc: _mono_signature_get_desc;
  mono_signature_is_instance: _mono_signature_is_instance;
  mono_signature_vararg_start: _mono_signature_vararg_start;
  mono_object_get_virtual_method: _mono_object_get_virtual_method;
  mono_class_is_valuetype: _mono_class_is_valuetype;
  mono_method_get_class: _mono_method_get_class;
  mono_class_get_name: _mono_class_get_name;
  mono_class_get_namespace: _mono_class_get_namespace;
  mono_class_get_image: _mono_class_get_image;
  mono_type_full_name: _mono_type_full_name;
  mono_class_from_mono_type: _mono_class_from_mono_type;
  mono_class_get_parent: _mono_class_get_parent;
  mono_object_new: _mono_object_new;
  mono_object_get_class: _mono_object_get_class;
  mono_runtime_object_init: _mono_runtime_object_init;
  mono_object_unbox: _mono_object_unbox;
  mono_value_box: _mono_value_box;
  mono_runtime_invoke: _mono_runtime_invoke;
  mono_string_new_utf16: _mono_string_new_utf16;
  mono_string_to_byvalwstr: _mono_string_to_byvalwstr;
  mono_string_to_utf16: _mono_string_to_utf16;
  mono_get_corlib: _mono_get_corlib;
  mono_get_object_class: _mono_get_object_class;
  mono_get_byte_class: _mono_get_byte_class;
  mono_get_void_class: _mono_get_void_class;
  mono_get_boolean_class: _mono_get_boolean_class;
  mono_get_sbyte_class: _mono_get_sbyte_class;
  mono_get_int16_class: _mono_get_int16_class;
  mono_get_uint16_class: _mono_get_uint16_class;
  mono_get_int32_class: _mono_get_int32_class;
  mono_get_uint32_class: _mono_get_uint32_class;
  mono_get_intptr_class: _mono_get_intptr_class;
  mono_get_uintptr_class: _mono_get_uintptr_class;
  mono_get_int64_class: _mono_get_int64_class;
  mono_get_uint64_class: _mono_get_uint64_class;
  mono_get_single_class: _mono_get_single_class;
  mono_get_double_class: _mono_get_double_class;
  mono_get_char_class: _mono_get_char_class;
  mono_get_string_class: _mono_get_string_class;
  mono_get_enum_class: _mono_get_enum_class;
  mono_get_array_class: _mono_get_array_class;
  mono_get_thread_class: _mono_get_thread_class;
  mono_get_exception_class: _mono_get_exception_class;
  mono_set_dirs: _mono_set_dirs;
  mono_free: _mono_free;

  mono_array_class_get :_mono_array_class_get;
  mono_array_element_size :_mono_array_element_size;
  mono_class_array_element_size :_mono_class_array_element_size;
  mono_array_new :_mono_array_new;
  mono_array_new_full :_mono_array_new_full;
  mono_array_new_specific :_mono_array_new_specific;
  mono_array_clone :_mono_array_clone;
  mono_array_addr_with_size :_mono_array_addr_with_size;
  mono_array_length :_mono_array_length;
  mono_value_copy :_mono_value_copy;
  mono_value_copy_array :_mono_value_copy_array;
  mono_gchandle_new :_mono_gchandle_new;
  mono_gchandle_new_weakref :_mono_gchandle_new_weakref;
  mono_gchandle_get_target :_mono_gchandle_get_target;
  mono_gchandle_free :_mono_gchandle_free;

  mono_gc_wbarrier_set_field : _mono_gc_wbarrier_set_field;
  mono_gc_wbarrier_set_arrayref : _mono_gc_wbarrier_set_arrayref;
  mono_gc_wbarrier_arrayref_copy : _mono_gc_wbarrier_arrayref_copy;
  mono_gc_wbarrier_generic_store : _mono_gc_wbarrier_generic_store;
  mono_gc_wbarrier_generic_nostore : _mono_gc_wbarrier_generic_nostore;
  mono_gc_wbarrier_value_copy : _mono_gc_wbarrier_value_copy;
  mono_gc_wbarrier_object_copy : _mono_gc_wbarrier_object_copy;
  mono_gc_collect : _mono_gc_collect;
  mono_gc_max_generation : _mono_gc_max_generation;
  mono_gc_get_generation : _mono_gc_get_generation;
  mono_gc_collection_count : _mono_gc_collection_count;
  mono_gc_get_used_size : _mono_gc_get_used_size;
  mono_gc_get_heap_size : _mono_gc_get_heap_size;
  mono_gc_invoke_finalizers : _mono_gc_invoke_finalizers;
  mono_object_castclass_mbyref: _mono_object_castclass_mbyref;
  mono_class_get_flags: _mono_class_get_flags;
  mono_class_vtable: _mono_class_vtable;
  mono_class_interface_offset: _mono_class_interface_offset;
  mono_class_get_interfaces: _mono_class_get_interfaces;
  mono_class_get_type : _mono_class_get_type;
  mono_class_get_byref_type : _mono_class_get_byref_type;
  mono_class_instance_size: _mono_class_instance_size;
  mono_class_data_size: _mono_class_data_size;
  mono_class_value_size: _mono_class_value_size;
  mono_class_min_align: _mono_class_min_align;
  mono_field_get_name: _mono_field_get_name;
  mono_field_get_type: _mono_field_get_type;
  mono_field_get_flags: _mono_field_get_flags;
  mono_field_set_value: _mono_field_set_value;
  mono_field_static_set_value: _mono_field_static_set_value;
  mono_field_get_value: _mono_field_get_value;
  mono_field_static_get_value: _mono_field_static_get_value;
  mono_field_get_value_object: _mono_field_get_value_object;
  mono_field_get_offset: _mono_field_get_offset;
  mono_field_get_data: _mono_field_get_data;
  mono_get_dbnull_object: _mono_get_dbnull_object;

  mono_runtime_delegate_invoke: _mono_runtime_delegate_invoke;
  mono_get_delegate_invoke: _mono_get_delegate_invoke;
  mono_method_get_unmanaged_thunk: _mono_method_get_unmanaged_thunk;

  mono_install_assembly_load_hook: _mono_install_assembly_load_hook;
  mono_image_get_filename: _mono_image_get_filename;
  mono_image_get_name: _mono_image_get_name;
  mono_assembly_foreach: _mono_assembly_foreach;
  mono_assembly_open: _mono_assembly_open;
  mono_object_get_domain: _mono_object_get_domain;
  mono_domain_get: _mono_domain_get;
  mono_domain_get_by_id: _mono_domain_get_by_id;
  mono_domain_get_id: _mono_domain_get_id;
  mono_domain_create_appdomain: _mono_domain_create_appdomain;
  mono_domain_set: _mono_domain_set;
  mono_domain_unload: _mono_domain_unload;
  mono_domain_try_unload: _mono_domain_try_unload;
  mono_domain_foreach: _mono_domain_foreach;

  mono_thread_init: _mono_thread_init;
  mono_thread_cleanup: _mono_thread_cleanup;
  mono_thread_manage: _mono_thread_manage;
  mono_thread_current: _mono_thread_current;
  mono_thread_set_main: _mono_thread_set_main;
  mono_thread_get_main: _mono_thread_get_main;
  mono_thread_stop: _mono_thread_stop;
  mono_thread_new_init: _mono_thread_new_init;
  mono_thread_create: _mono_thread_create;
  mono_thread_attach: _mono_thread_attach;
  mono_thread_detach: _mono_thread_detach;
  mono_thread_set_manage_callback: _mono_thread_set_manage_callback;
  mono_threads_set_default_stacksize: _mono_threads_set_default_stacksize;
  mono_threads_get_default_stacksize: _mono_threads_get_default_stacksize;

  type
    PMonoStringBuilder = Pointer;

procedure GetArrayValue(_array: PMonoArray; _typesize: integer; idx: NativeUInt; out aValue);
procedure SetArrayValue(_array: PMonoArray; _typesize: integer; idx: NativeUInt; const aValue);
procedure SetArrayRef(_array: PMonoArray; idx: NativeUInt; const aValue);
procedure CopyArrayRef(dest: PMonoArray; destidx: NativeUInt; src: PMonoArray; srcidx: NativeUint; count: NativeInt);
function MonoClassIsInterface(klass: PMonoClass): boolean;
function ElemClassArray(aType: PMonoType): PMonoClass;

procedure SetMonoPath(aPath: string);
procedure InitMono;
procedure FreeMono;

implementation
uses
  Windows, sysutils, dialogs;
var
  hMonoLib: HMODULE;

procedure GetArrayValue(_array: PMonoArray; _typesize: integer; idx: NativeUInt; out aValue);
var
  pb: PByte;
begin
  //move(aParams.vector, lParams[0], aParams.max_length * sizeof(PMonoObject));
  pb := mono_array_addr_with_size(_array, _typesize, idx);
  move(pb^, aValue, _typesize);
end;

procedure SetArrayValue(_array: PMonoArray; _typesize: integer; idx: NativeUInt; const aValue);
var
  pb: PByte;
begin
  pb := mono_array_addr_with_size(_array, _typesize, idx);
  move(aValue, pb^, _typesize);
end;

procedure SetArrayRef(_array: PMonoArray; idx: NativeUInt; const aValue);
var
  pb: PByte;
begin
  pb := mono_array_addr_with_size(_array, sizeof(PMonoObject), idx);
  mono_gc_wbarrier_set_arrayref(_array, Pointer(pb), PMonoObject(aValue));
end;

procedure CopyArrayRef(dest: PMonoArray; destidx: NativeUInt; src: PMonoArray; srcidx: NativeUint; count: NativeInt);
var
  d,s: PByte;
begin
  d := mono_array_addr_with_size(dest, sizeof(Pointer), destidx);
  s := mono_array_addr_with_size(src, sizeof(Pointer), srcidx);
  mono_gc_wbarrier_arrayref_copy(@d, @s, count);
end;

function MonoClassIsInterface(klass: PMonoClass): boolean;
begin
  //((c->flags & TYPE_ATTRIBUTE_INTERFACE) || (c->byval_arg.type == MONO_TYPE_VAR) || (c->byval_arg.type == MONO_TYPE_MVAR))
  result := (mono_class_get_flags(klass) and TYPE_ATTRIBUTE_INTERFACE) = TYPE_ATTRIBUTE_INTERFACE;
end;

function ElemClassArray(aType: PMonoType): PMonoClass;
begin
  result := aType^.data.array_^.eklass;
end;

function TMonoType.attrs: cardinal;
begin
  result := flags and $0000FFFF;    // primi 16 bit
end;

function TMonoType.type_: TMonoTypeEnum;
var
  c: cardinal;
begin
  // 00000000111111110000000000000000 = 00FF0000
  c := flags and $00FF0000;
  c := c shr 16;
  result := TMonoTypeEnum(c);
end;

function TMonoType.num_mods: cardinal;
begin
  // 00111111000000000000000000000000 = 3F000000
  result := flags and $3F000000;
  result := result shr 24;
end;

function TMonoType.byRef: cardinal;
begin
  // 01000000000000000000000000000000 = 40000000
  result := flags and $40000000;
  result := result shr 30;
end;

function TMonoType.pinned: cardinal;
begin
  // 10000000000000000000000000000000 = 80000000
  result := flags and $80000000;
  result := result shr 31;
end;

function TMonoCustomMod.required: cardinal;
begin
  // 00000000000000000000000000000001 = 00000001
  result := flags and $00000001;
end;

function TMonoCustomMod.token: cardinal;
begin
  // 11111111111111111111111111111110 = FFFFFFFE
  result := flags and $FFFFFFFE;
  result := result shr 1;
end;

procedure SetMonoPath(aPath: string);
var
  lPath: string;
begin
  lPath := GetEnvironmentVariable('PATH');
  if lPath <> '' then
    lPath := aPath+';'+lPath
  else
    lPath := aPath;
  SetEnvironmentVariable('PATH', PWideChar(lPath));
end;


function GetProc(const Name: string): Pointer;
begin
{$IFDEF MSWINDOWS}
  Result := GetProcAddress(hMonoLib, PChar(Name));
{$ENDIF}
{$IFDEF LINUX}
  Result := dlsym(hMonoLib, PChar(Name));
{$ENDIF}
  if Result = nil then
    ShowMessage('Not Found '+Name);
end;

procedure InitMono;
begin
  hMonoLib := LoadLibraryEx(PChar(MONODLL), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
  if Integer(hMonoLib) = 0 then
      raise Exception.Create('Cannot load client DLL: ' + MONODLL);

  // load function
  //func := GetProc('');
  mono_jit_init := GetProc('mono_jit_init');
  mono_jit_init_version := GetProc('mono_jit_init_version');
  mono_jit_exec := GetProc('mono_jit_exec');
  mono_jit_cleanup := GetProc('mono_jit_cleanup');
  mono_jit_parse_options := GetProc('mono_jit_parse_options');
  mono_debug_init := GetProc('mono_debug_init');
  mono_domain_assembly_open := GetProc('mono_domain_assembly_open');
  mono_add_internal_call := GetProc('mono_add_internal_call');
  mono_assembly_get_image := GetProc('mono_assembly_get_image');
  mono_class_from_name := GetProc('mono_class_from_name');
  mono_class_get_field_from_name := GetProc('mono_class_get_field_from_name');
  mono_type_get_type := GetProc('mono_type_get_type');
  mono_type_is_byref := GetProc('mono_type_is_byref');
  mono_type_get_name := GetProc('mono_type_get_name');
  mono_class_get_method_from_name := GetProc('mono_class_get_method_from_name');
  mono_class_get_methods := GetProc('mono_class_get_methods');
  mono_class_get_fields := GetProc('mono_class_get_fields');
  mono_class_get_properties := GetProc('mono_class_get_properties');
  mono_class_get_events := GetProc('mono_class_get_events');
  mono_class_get_property_from_name := GetProc('mono_class_get_property_from_name');
  mono_property_get_get_method := GetProc('mono_property_get_get_method');
  mono_property_get_value := GetProc('mono_property_get_value');
  mono_property_set_value := GetProc('mono_property_set_value');
  mono_property_get_name := GetProc('mono_property_get_name');
  mono_property_get_set_method := GetProc('mono_property_get_set_method');
  mono_property_get_parent := GetProc('mono_property_get_parent');
  mono_property_get_flags := GetProc('mono_property_get_flags');
  mono_method_get_name := GetProc('mono_method_get_name');
  mono_method_signature := GetProc('mono_method_signature');
  mono_signature_get_param_count := GetProc('mono_signature_get_param_count');
  mono_signature_get_params := GetProc('mono_signature_get_params');
  mono_signature_get_return_type := GetProc('mono_signature_get_return_type');
  mono_signature_get_desc := GetProc('mono_signature_get_desc');
  mono_signature_is_instance := GetProc('mono_signature_is_instance');
  mono_signature_vararg_start := GetProc('mono_signature_vararg_start');
  mono_object_get_virtual_method := GetProc('mono_object_get_virtual_method');
  mono_class_is_valuetype := GetProc('mono_class_is_valuetype');
  mono_method_get_class := GetProc('mono_method_get_class');
  mono_class_get_name := GetProc('mono_class_get_name');
  mono_class_get_namespace := GetProc('mono_class_get_namespace');
  mono_class_get_image := GetProc('mono_class_get_image');
  mono_type_full_name := GetProc('mono_type_full_name');
  mono_class_from_mono_type := GetProc('mono_class_from_mono_type');
  mono_class_get_parent := GetProc('mono_class_get_parent');
  mono_object_new := GetProc('mono_object_new');
  mono_object_get_class := GetProc('mono_object_get_class');
  mono_runtime_object_init := GetProc('mono_runtime_object_init');
  mono_object_unbox := GetProc('mono_object_unbox');
  mono_value_box := GetProc('mono_value_box');
  mono_runtime_invoke := GetProc('mono_runtime_invoke');
  mono_string_new_utf16 := GetProc('mono_string_new_utf16');
  mono_string_to_byvalwstr := GetProc('mono_string_to_byvalwstr');
  mono_string_to_utf16 := GetProc('mono_string_to_utf16');
  mono_get_corlib := GetProc('mono_get_corlib');
  mono_get_object_class := GetProc('mono_get_object_class');
  mono_get_byte_class := GetProc('mono_get_byte_class');
  mono_get_void_class := GetProc('mono_get_void_class');
  mono_get_boolean_class := GetProc('mono_get_boolean_class');
  mono_get_sbyte_class := GetProc('mono_get_sbyte_class');
  mono_get_int16_class := GetProc('mono_get_int16_class');
  mono_get_uint16_class := GetProc('mono_get_uint16_class');
  mono_get_int32_class := GetProc('mono_get_int32_class');
  mono_get_uint32_class := GetProc('mono_get_uint32_class');
  mono_get_intptr_class := GetProc('mono_get_intptr_class');
  mono_get_uintptr_class := GetProc('mono_get_uintptr_class');
  mono_get_int64_class := GetProc('mono_get_int64_class');
  mono_get_uint64_class := GetProc('mono_get_uint64_class');
  mono_get_single_class := GetProc('mono_get_single_class');
  mono_get_double_class := GetProc('mono_get_double_class');
  mono_get_char_class := GetProc('mono_get_char_class');
  mono_get_string_class := GetProc('mono_get_string_class');
  mono_get_enum_class := GetProc('mono_get_enum_class');
  mono_get_array_class := GetProc('mono_get_array_class');
  mono_get_thread_class := GetProc('mono_get_thread_class');
  mono_get_exception_class := GetProc('mono_get_exception_class');
  mono_set_dirs := GetProc('mono_set_dirs');
  mono_free := GetProc('mono_free');
  mono_array_class_get := GetProc('mono_array_class_get');
  mono_array_element_size := GetProc('mono_array_element_size');
  mono_class_array_element_size := GetProc('mono_class_array_element_size');
  mono_array_new := GetProc('mono_array_new');
  mono_array_new_full := GetProc('mono_array_new_full');
  mono_array_new_specific := GetProc('mono_array_new_specific');
  mono_array_clone := GetProc('mono_array_clone');
  mono_array_addr_with_size := GetProc('mono_array_addr_with_size');
  mono_array_length := GetProc('mono_array_length');
  mono_value_copy := GetProc('mono_value_copy');
  mono_value_copy_array := GetProc('mono_value_copy_array');
  mono_gchandle_new := GetProc('mono_gchandle_new');
  mono_gchandle_new_weakref := GetProc('mono_gchandle_new_weakref');
  mono_gchandle_get_target := GetProc('mono_gchandle_get_target');
  mono_gchandle_free := GetProc('mono_gchandle_free');
  mono_gc_wbarrier_set_field := GetProc('mono_gc_wbarrier_set_field');
  mono_gc_wbarrier_set_arrayref := GetProc('mono_gc_wbarrier_set_arrayref');
  mono_gc_wbarrier_arrayref_copy := GetProc('mono_gc_wbarrier_arrayref_copy');
  mono_gc_wbarrier_generic_store := GetProc('mono_gc_wbarrier_generic_store');
  mono_gc_wbarrier_generic_nostore := GetProc('mono_gc_wbarrier_generic_nostore');
  mono_gc_wbarrier_value_copy := GetProc('mono_gc_wbarrier_value_copy');
  mono_gc_wbarrier_object_copy := GetProc('mono_gc_wbarrier_object_copy');
  mono_gc_collect := GetProc('mono_gc_collect');
  mono_gc_max_generation := GetProc('mono_gc_max_generation');
  mono_gc_get_generation := GetProc('mono_gc_get_generation');
  mono_gc_collection_count := GetProc('mono_gc_collection_count');
  mono_gc_get_used_size := GetProc('mono_gc_get_used_size');
  mono_gc_get_heap_size := GetProc('mono_gc_get_heap_size');
  mono_gc_invoke_finalizers := GetProc('mono_gc_invoke_finalizers');
  mono_object_castclass_mbyref := GetProc('mono_object_castclass_mbyref');
  mono_class_get_flags := GetProc('mono_class_get_flags');
  mono_class_vtable := GetProc('mono_class_vtable');
  mono_class_interface_offset := GetProc('mono_class_interface_offset');
  mono_class_get_interfaces := GetProc('mono_class_get_interfaces');
  mono_class_get_type := GetProc('mono_class_get_type');
  mono_class_get_byref_type := GetProc('mono_class_get_byref_type');
  mono_class_instance_size := GetProc('mono_class_instance_size');
  mono_class_data_size := GetProc('mono_class_data_size');
  mono_class_value_size := GetProc('mono_class_value_size');
  mono_class_min_align := GetProc('mono_class_min_align');
  mono_field_get_name := GetProc('mono_field_get_name');
  mono_field_get_type := GetProc('mono_field_get_type');
  mono_field_get_flags := GetProc('mono_field_get_flags');
  mono_field_set_value := GetProc('mono_field_set_value');
  mono_field_static_set_value := GetProc('mono_field_static_set_value');
  mono_field_get_value := GetProc('mono_field_get_value');
  mono_field_static_get_value := GetProc('mono_field_static_get_value');
  mono_field_get_value_object := GetProc('mono_field_get_value_object');
  mono_field_get_offset := GetProc('mono_field_get_offset');
  mono_field_get_data := GetProc('mono_field_get_data');
  mono_get_dbnull_object := GetProc('mono_get_dbnull_object');
  mono_runtime_delegate_invoke := GetProc('mono_runtime_delegate_invoke');
  mono_get_delegate_invoke := GetProc('mono_get_delegate_invoke');
  mono_method_get_unmanaged_thunk := GetProc('mono_method_get_unmanaged_thunk');

  mono_install_assembly_load_hook := GetProc('mono_install_assembly_load_hook');
  mono_image_get_filename := GetProc('mono_image_get_filename');
  mono_image_get_name := GetProc('mono_image_get_name');
  mono_assembly_foreach := GetProc('mono_assembly_foreach');
  mono_assembly_open := GetProc('mono_assembly_open');
  mono_object_get_domain := GetProc('mono_object_get_domain');
  mono_domain_get := GetProc('mono_domain_get');
  mono_domain_get_by_id := GetProc('mono_domain_get_by_id');
  mono_domain_get_id := GetProc('mono_domain_get_id');
  mono_domain_create_appdomain := GetProc('mono_domain_create_appdomain');
  mono_domain_set := GetProc('mono_domain_set');
  mono_domain_unload := GetProc('mono_domain_unload');
  mono_domain_try_unload := GetProc('mono_domain_try_unload');
  mono_domain_foreach := GetProc('mono_domain_foreach');

  mono_thread_init := GetProc('mono_thread_init');
  mono_thread_cleanup := GetProc('mono_thread_cleanup');
  mono_thread_manage := GetProc('mono_thread_manage');
  mono_thread_current := GetProc('mono_thread_current');
  mono_thread_set_main := GetProc('mono_thread_set_main');
  mono_thread_get_main := GetProc('mono_thread_get_main');
  mono_thread_stop := GetProc('mono_thread_stop');
  mono_thread_new_init := GetProc('mono_thread_new_init');
  mono_thread_create := GetProc('mono_thread_create');
  mono_thread_attach := GetProc('mono_thread_attach');
  mono_thread_detach := GetProc('mono_thread_detach');
  mono_thread_set_manage_callback := GetProc('mono_thread_set_manage_callback');
  mono_threads_set_default_stacksize := GetProc('mono_threads_set_default_stacksize');
  mono_threads_get_default_stacksize := GetProc('mono_threads_get_default_stacksize');
end;

procedure FreeMono;
begin
  mono_jit_init := nil;
  mono_jit_init_version := nil;
  mono_jit_exec := nil;
  mono_jit_cleanup := nil;
  mono_jit_parse_options := nil;
  mono_debug_init := nil;
  mono_domain_assembly_open := nil;
  mono_add_internal_call := nil;
  mono_assembly_get_image := nil;
  mono_class_from_name := nil;
  mono_class_get_field_from_name := nil;
  mono_type_get_type := nil;
  mono_type_is_byref := nil;
  mono_type_get_name := nil;
  mono_class_get_method_from_name := nil;
  mono_class_get_methods := nil;
  mono_class_get_fields := nil;
  mono_class_get_properties := nil;
  mono_class_get_events := nil;
  mono_class_get_property_from_name := nil;
  mono_property_get_get_method := nil;
  mono_property_get_value := nil;
  mono_property_set_value := nil;
  mono_property_get_name := nil;
  mono_property_get_set_method := nil;
  mono_property_get_parent := nil;
  mono_property_get_flags := nil;
  mono_method_get_name := nil;
  mono_method_signature := nil;
  mono_signature_get_param_count := nil;
  mono_signature_get_params := nil;
  mono_signature_get_return_type := nil;
  mono_signature_get_desc := nil;
  mono_signature_is_instance := nil;
  mono_signature_vararg_start := nil;
  mono_object_get_virtual_method := nil;
  mono_class_is_valuetype := nil;
  mono_method_get_class := nil;
  mono_class_get_name := nil;
  mono_class_get_namespace := nil;
  mono_class_get_image := nil;
  mono_type_full_name := nil;
  mono_class_from_mono_type := nil;
  mono_class_get_parent := nil;
  mono_object_new := nil;
  mono_object_get_class := nil;
  mono_runtime_object_init := nil;
  mono_object_unbox := nil;
  mono_value_box := nil;
  mono_runtime_invoke := nil;
  mono_string_new_utf16 := nil;
  mono_string_to_byvalwstr := nil;
  mono_string_to_utf16 := nil;
  mono_get_corlib := nil;
  mono_get_object_class := nil;
  mono_get_byte_class := nil;
  mono_get_void_class := nil;
  mono_get_boolean_class := nil;
  mono_get_sbyte_class := nil;
  mono_get_int16_class := nil;
  mono_get_uint16_class := nil;
  mono_get_int32_class := nil;
  mono_get_uint32_class := nil;
  mono_get_intptr_class := nil;
  mono_get_uintptr_class := nil;
  mono_get_int64_class := nil;
  mono_get_uint64_class := nil;
  mono_get_single_class := nil;
  mono_get_double_class := nil;
  mono_get_char_class := nil;
  mono_get_string_class := nil;
  mono_get_enum_class := nil;
  mono_get_array_class := nil;
  mono_get_thread_class := nil;
  mono_get_exception_class := nil;
  mono_set_dirs := nil;
  mono_free := nil;
  mono_array_class_get := nil;
  mono_array_element_size := nil;
  mono_class_array_element_size := nil;
  mono_array_new := nil;
  mono_array_new_full := nil;
  mono_array_new_specific := nil;
  mono_array_clone := nil;
  mono_array_addr_with_size := nil;
  mono_array_length := nil;
  mono_value_copy := nil;
  mono_value_copy_array := nil;
  mono_gchandle_new := nil;
  mono_gchandle_new_weakref := nil;
  mono_gchandle_get_target := nil;
  mono_gchandle_free := nil;
  mono_gc_wbarrier_set_field := nil;
  mono_gc_wbarrier_set_arrayref := nil;
  mono_gc_wbarrier_arrayref_copy := nil;
  mono_gc_wbarrier_generic_store := nil;
  mono_gc_wbarrier_generic_nostore := nil;
  mono_gc_wbarrier_value_copy := nil;
  mono_gc_wbarrier_object_copy := nil;
  mono_gc_collect := nil;
  mono_gc_max_generation := nil;
  mono_gc_get_generation := nil;
  mono_gc_collection_count := nil;
  mono_gc_get_used_size := nil;
  mono_gc_get_heap_size := nil;
  mono_gc_invoke_finalizers := nil;

  mono_object_castclass_mbyref := nil;
  mono_class_get_flags := nil;
  mono_class_vtable := nil;
  mono_class_interface_offset := nil;
  mono_class_get_interfaces := nil;
  mono_class_get_type := nil;
  mono_class_get_byref_type := nil;
  mono_class_instance_size := nil;
  mono_class_data_size := nil;
  mono_class_value_size := nil;
  mono_class_min_align := nil;
  mono_field_get_name := nil;
  mono_field_get_type := nil;
  mono_field_get_flags := nil;
  mono_field_set_value := nil;
  mono_field_static_set_value := nil;
  mono_field_get_value := nil;
  mono_field_static_get_value := nil;
  mono_field_get_value_object := nil;
  mono_field_get_offset := nil;
  mono_field_get_data := nil;
  mono_get_dbnull_object := nil;
  mono_runtime_delegate_invoke := nil;
  mono_get_delegate_invoke := nil;
  mono_method_get_unmanaged_thunk := nil;

  mono_install_assembly_load_hook := nil;
  mono_image_get_filename := nil;
  mono_image_get_name := nil;
  mono_assembly_foreach := nil;
  mono_assembly_open := nil;
  mono_object_get_domain := nil;
  mono_domain_get := nil;
  mono_domain_get_by_id := nil;
  mono_domain_get_id := nil;
  mono_domain_create_appdomain := nil;
  mono_domain_set := nil;
  mono_domain_unload := nil;
  mono_domain_try_unload := nil;
  mono_domain_foreach := nil;

  mono_thread_init := nil;
  mono_thread_cleanup := nil;
  mono_thread_manage := nil;
  mono_thread_current := nil;
  mono_thread_set_main := nil;
  mono_thread_get_main := nil;
  mono_thread_stop := nil;
  mono_thread_new_init := nil;
  mono_thread_create := nil;
  mono_thread_attach := nil;
  mono_thread_detach := nil;
  mono_thread_set_manage_callback := nil;
  mono_threads_set_default_stacksize := nil;
  mono_threads_get_default_stacksize := nil;
  //FreeLibrary(hMonoLib);
  hMonoLib := 0;
end;



end.
